package easypay

import (
	"context"
	"errors"
	"fmt"

	"gitee.com/liuxuezhan/ar-platform/admin-api/internal/pay/base"
	xerrors "gitee.com/liuxuezhan/ar-platform/admin-api/pkg/xerrors/assets"

	"github.com/bytedance/sonic/decoder"
	"github.com/zeromicro/go-zero/core/logc"
)

type Factory struct {
}

func (p *Factory) CreatePay(config base.Config) base.Payment {
	return &Easypay{
		Url:        config.Url,
		MerchantId: config.MerchantId,
		SecretKey:  config.SecretKey,
		ReturnUrl:  config.ReturnUrl,
		NotifyUrl:  config.NotifyUrl,
	}
}

type Easypay struct {
	MerchantId string
	SecretKey  string
	Url        string
	ReturnUrl  string
	NotifyUrl  string
}

type Resp struct {
	Code string `json:"Code"`
	Msg  string `json:"Message"`
	Data any    `json:"Data"`
}

// 代收订单创建
func (p *Easypay) Withdraw(ctx context.Context, req map[string]any) (resp base.WithdrawRes, err error) {
	// 请求第三方接口
	url := p.Url + "/api/v1/trade/withdraw/create"
	params := make(map[string]any)
	params["merchantId"] = p.MerchantId
	params["tradeNumber"] = req["Order"].(map[string]any)["OrderNo"]
	params["currency"] = "INR"
	params["amount"] = fmt.Sprintf("%.2f", req["Order"].(map[string]any)["RealAmount"].(float64))
	params["notifyUrl"] = p.NotifyUrl
	params["bankCode"] = "IMPS"
	params["accountNumber"] = req["Order"].(map[string]any)["UserBank"].(map[string]any)["CardNumber"]
	params["accountName"] = req["Order"].(map[string]any)["UserBank"].(map[string]any)["UserName"]
	params["accountIfsc"] = req["Order"].(map[string]any)["UserBank"].(map[string]any)["IfscCode"]
	params["attach"] = req["Order"].(map[string]any)["OrderNo"]
	reqSign, err := GenerateSignature(params, p.SecretKey)
	if err != nil {
		logc.Error(ctx, err)
		return base.WithdrawRes{}, xerrors.ErrSignGenerateFailed
	}
	params["sign"] = reqSign
	result, err := sendRequest(ctx, url, params, "post")
	if err != nil {
		return
	}

	// 验签
	// respSign, err := GenerateSignature(result.Data.(map[string]any), p.SecretKey)
	// if err != nil {
	// 	logc.Error(ctx, err)
	// 	return base.WithdrawRes{}, xerrors.ErrSignGenerateFailed
	// }
	// if respSign != result.Data.(map[string]any)["sign"] {
	// 	logc.Error(ctx, respSign, result)
	// 	return resp, xerrors.ErrSignVerifyFailed
	// }

	resp = base.WithdrawRes{
		OrderSn:      result.Data.(map[string]any)["merchantTradeNumber"].(string),
		ThirdOrderSn: result.Data.(map[string]any)["tradeNumber"].(string),
	}
	return
}

// 发送请求
func sendRequest(ctx context.Context, url string, params map[string]any, method string) (resp Resp, err error) {
	output, err := base.SendJson(ctx, url, params, method)
	if err != nil {
		return resp, err
	}
	dc := decoder.NewDecoder(output)
	dc.UseNumber()
	dc.Decode(&resp)
	if resp.Code != "SUCCESS" {
		return resp, errors.New(resp.Msg)
	}
	return
}
